In [ ]:
# Importamos la biblioteca TensorFlow para trabajar con redes neuronales y aprendizaje profundo.
import tensorflow as tf

# Importamos varias bibliotecas estándar y de terceros para diversas funcionalidades.

# Bibliotecas para manejo de archivos y tiempo.
import os
import time
import datetime
import random
import glob

# Bibliotecas numéricas y de análisis de datos.
import numpy as np
import pandas as pd
import scipy as sp

# Bibliotecas para visualización de datos.
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import plotly.io as pio

# Biblioteca para interactuar con bases de datos SQL.
from sqlalchemy import create_engine

# Biblioteca para cargar variables de entorno desde archivos .env.
from dotenv import load_dotenv

# Biblioteca para mostrar barras de progreso en bucles.
from tqdm import tqdm
2023-08-12 00:31:20.842694: I tensorflow/core/util/port.cc:110] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.
2023-08-12 00:31:23.200249: I tensorflow/core/platform/cpu_feature_guard.cc:182] This TensorFlow binary is optimized to use available CPU instructions in performance-critical operations.
To enable the following instructions: AVX2 AVX512F AVX512_VNNI FMA, in other operations, rebuild TensorFlow with the appropriate compiler flags.

Clase MDL - Creacion de modelo carril¶

La clase MDL es una implementación de Python que se utiliza para analizar datos de tráfico ferroviario y construir un Modelo de Aprendizaje Profundo (MDL) para predecir valores futuros. A continuación, se describen los principales métodos y funcionalidades de la clase:

Constructor __init__¶

El constructor inicializa la clase MDL con los siguientes parámetros:

  • rail: Carril para el análisis de tráfico.
  • date_min: Fecha mínima para el análisis.
  • date_max: Fecha máxima para el análisis.
  • feature_columns: Nombres de las columnas utilizadas como características.
  • target_columns: Nombres de las columnas utilizadas como etiquetas.
  • predict_columns: Nombres de las columnas utilizadas para las predicciones.

Método calculate_df¶

Este método realiza la manipulación y limpieza de los datos de tráfico. Realiza operaciones como:

  1. Ejecuta una consulta SQL para obtener datos de tráfico.
  2. Carga variables de entorno para la conexión a la base de datos.
  3. Crea un DataFrame con los datos obtenidos y realiza manipulaciones.
  4. Combina DataFrames y asigna el resultado a self.df.

Método calculate_data¶

Realiza el preprocesamiento de los datos almacenados en self.df. Elimina filas nulas y atípicas basadas en la puntuación Z.

Método calculate_mdl¶

Construye y entrena un Modelo de Aprendizaje Profundo utilizando una red neuronal secuencial. Utiliza la función de pérdida MAE y el optimizador Adam para el entrenamiento.

Método calculate_predict¶

Genera predicciones utilizando el modelo entrenado y agrega los resultados al DataFrame principal.

Método calculate_info¶

Realiza cálculos estadísticos y agrega información a un DataFrame de estadísticas. Calcula valores nulos, valores atípicos y varias métricas agregadas.


En resumen, la clase MDL se utiliza para analizar y preprocesar datos de tráfico , construir un Modelo de Aprendizaje Profundo y realizar análisis estadísticos sobre los resultados obtenidos. Cada método desempeña un papel crucial en el proceso de análisis de datos y construcción del modelo.

In [ ]:
class MDL:
    def __init__(self, *args, **kwargs):
        """
        Constructor de la clase MDL.
        
        Parámetros:
        - rail: Carril para el que se desea analizar el tráfico.
        - date_min: Fecha mínima para el análisis.
        - date_max: Fecha máxima para el análisis.
        - feature_columns: nombre de las columnas que el modelo toma como caracteristicas.
        - target_columns: nombre de las columnas que el modelo toma como etquitas.
        - predict_columns: nombre de las columnas que el modelo toma como etquitas para las predicciones
        """

        self.rail = kwargs.get('rail')

        self.date_min = kwargs.get('date_min')
        self.date_max = kwargs.get('date_max')

        self.feature_columns = kwargs.get('feature_columns')
        self.target_columns = kwargs.get('target_columns')
        self.predict_columns = kwargs.get('predict_columns')

        # Llamar a los métodos para calcular el DataFrame y la información
        self.calculate_df()
        self.calculate_data()
        self.calculate_mdl()
        self.calculate_predict()
        self.calculate_info()

    def calculate_df(self, *args, **kwargs):
        """
        Realiza un cálculo y manipulación de datos de tráfico a partir de una consulta SQL parametrizada.
        
        Este método realiza las siguientes operaciones:
        1. Ejecuta una consulta SQL parametrizada para obtener los datos de tráfico en un rango de fechas y carril especificado.
        2. Carga las variables de entorno desde un archivo .env para la conexión a la base de datos.
        3. Crea una conexión a la base de datos y lee los datos en un DataFrame.
        4. Realiza manipulación y limpieza de los datos en el DataFrame.
        5. Crea un DataFrame temporal con un rango de fechas y agrega columnas de tiempo para análisis posterior.
        6. Combina los DataFrames por fecha y asigna el resultado a self.df.

        Args:
            *args: Argumentos posicionales (no se utilizan en este método).
            **kwargs: Argumentos clave (no se utilizan en este método).

        Returns:
            None. El DataFrame resultante se asigna a self.df en la instancia de la clase.
        """
        # Consulta SQL parametrizada para obtener los datos de tráfico en el rango de fechas y carril especificado
        template_sql = """
        SELECT Fecha AS date_hour, Intensidad AS value_intensity_real, Velocidad AS value_speed_real
        FROM [MEDELLIN_GIP].[dbo].DatosTrafico_Hora
        WHERE Fecha >= '{date_min}' AND Fecha <= '{date_max}' AND Carril = '{rail}';
        """
        
        # Rellenar los valores en la consulta SQL
        sql = template_sql.format(rail=self.rail, date_min=self.date_min, date_max=self.date_max)

        # Cargar variables de entorno desde archivo .env para la conexión a la base de datos
        load_dotenv()
        user = os.getenv('user')
        password = os.getenv('password')
        localhost = os.getenv('localhost')
        port = os.getenv('port')
        database = os.getenv('database')

        # Crear una conexión a la base de datos y leer los datos en un DataFrame
        engine = create_engine(f'mssql+pymssql://{user}:{password}@{localhost}:{port}/{database}', echo=False)
        connection = engine.connect()
        df = pd.read_sql(sql=sql, con=connection)

        # Manipulación y limpieza de los datos en el DataFrame
        df['date_hour'] = pd.to_datetime(df["date_hour"])
        df['date_hour'] = df['date_hour'].dt.round('1h')
        df.drop_duplicates(subset=['date_hour'], inplace=True)
        
        # Cerrar la conexion a la base de datos
        connection.close()

        # Crear un DataFrame temporal con un rango de fechas
        df_tmp = pd.DataFrame(dict(date_hour=pd.date_range(start=self.date_min, end=self.date_max, freq='H')))
        df_tmp['date_hour'] = pd.to_datetime(df_tmp['date_hour'])
        df_tmp['rail'] = int(self.rail)

        # Agregar columnas de tiempo para análisis temporal posterior
        df_tmp['year'] = [i.year for i in df_tmp['date_hour']]
        df_tmp['month'] = [i.month for i in df_tmp['date_hour']]
        df_tmp['day'] = [i.day for i in df_tmp['date_hour']]
        df_tmp['hour'] = [i.hour for i in df_tmp['date_hour']]

        df_tmp['day_of_week'] = [i.dayofweek for i in df_tmp['date_hour']]
        df_tmp['week_of_year'] = [i.week for i in df_tmp['date_hour']]
        df_tmp['day_of_year'] = [i.dayofyear for i in df_tmp['date_hour']]

        # Combinar DataFrames por fecha
        df = pd.merge(df_tmp, df, on='date_hour', how='left')
        self.df = df
    
   
    def calculate_data(self, *args, **kwargs):
        """
        Realiza el cálculo y preprocesamiento de los datos en el DataFrame.

        Este método toma el DataFrame almacenado en el objeto y realiza las siguientes operaciones de preprocesamiento:
        1. Elimina filas con valores nulos.
        2. Elimina filas con valores atípicos basados en la puntuación Z.
        3. Almacena el DataFrame preprocesado en el atributo 'df_data' del objeto.

        Args:
            *args: Argumentos posicionales opcionales.
            **kwargs: Argumentos clave opcionales.

        Returns:
            None
        """
        
        df=self.df.copy()
        
        # Eliminar los datos null
        df.dropna(inplace=True)
        
        # Eliminar los datos atipicos
        df = df[ (np.abs(sp.stats.zscore(df['value_intensity_real'])) <= 3.0) & (np.abs(sp.stats.zscore(df['value_speed_real'])) <= 3.0)]
        
        # Almacenar el DataFrame con información limpia de nulos y datos atipicos para el entrenamiento del modelo
        self.df_data = df

    def calculate_mdl(self, *args, **kwargs):
        """
        Calcula el Modelo de Aprendizaje Profundo (MDL) utilizando una red neuronal secuencial.

        Este método construye una red neuronal secuencial con capas densas y lo entrena con los datos
        de características y objetivos proporcionados en el DataFrame df_data. Utiliza la función de pérdida
        de error absoluto medio (MAE) y el optimizador Adam para el entrenamiento.

        Args:
            args: Argumentos posicionales adicionales (no se utilizan en este método).
            kwargs: Argumentos clave adicionales (no se utilizan en este método).

        Returns:
            None

        Nota:
            Este método modifica los siguientes atributos de la instancia:
            - score: El valor de la métrica de error absoluto medio (MAE) del modelo en los datos de entrenamiento.
            - model: El modelo de red neuronal entrenado.

        """
        n_outputs=len(self.target_columns)
        
        model = tf.keras.models.Sequential([
            tf.keras.layers.Dense(128, activation='relu'),
            tf.keras.layers.Dense(128, activation='relu'),
            tf.keras.layers.Dense(128, activation='relu'),
            tf.keras.layers.Dense(128, activation='relu'),
            tf.keras.layers.Dense(n_outputs, activation='linear')
        ])

        model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss=tf.keras.metrics.mae, metrics=[tf.keras.metrics.mae])

        model.fit(self.df_data[self.feature_columns], self.df_data[self.target_columns], epochs=100, batch_size=25, validation_split=0.2, validation_steps=10, verbose=0)

        self.score = model.evaluate(self.df_data[self.feature_columns], self.df_data[self.target_columns])            

        self.model=model
    
    def calculate_predict(self, *args, **kwargs):

        self.df_final=pd.concat([self.df.reset_index(drop=True), pd.DataFrame(data=self.model.predict(self.df[self.feature_columns]), columns=self.predict_columns)],axis=1)
    
    def calculate_info(self, *args, **kwargs):
        """
        Realiza cálculos estadísticos y agrega información a un DataFrame.
        
        Este método calcula diversas estadísticas y agregaciones sobre los datos en un DataFrame
        y almacena los resultados en otro DataFrame llamado 'df_info'. Las estadísticas calculadas
        incluyen valores nulos, valores atípicos y agregaciones de datos en función de distintas
        métricas y atributos.
        
        Args:
            *args: Argumentos posicionales (no se utilizan en este método).
            **kwargs: Argumentos clave (no se utilizan en este método).
            
        Returns:
            None
        
        """
        groups = [
            "rail",
        ]

        # Funciones personalizadas para cálculos estadísticos
        
        # Funcion para calcular los datos nulos
        def sum_isnan(x):
            return np.isnan(x).sum()
        
        # Funcion para calcular los porcentaje de datos nulos
        def percent_isnan(x):
            return np.isnan(x).sum() * 100 / np.size(x)
        
        # Funcion para calcular los la cantidad de datos atipicos
        def noutlier(x):
            return np.array(np.where(np.abs(sp.stats.zscore(x[~np.isnan(x)])) > 3)).size
        
        # Funcion para calcular los la cantidad porcentual de datos atipicos
        def percent_noutlier(x):
            return np.array(np.where(np.abs(sp.stats.zscore(x[~np.isnan(x)])) > 3)).size / np.size(x)

        # Definición de agregaciones para el análisis estadístico
        aggs = dict(
            date_hour=['min', 'max'],
            value_intensity_real=['sum', 'min', 'mean', 'max', 'count', 'size', sum_isnan, percent_isnan, noutlier, percent_noutlier],
            value_speed_real=['sum', 'min', 'mean', 'max', 'count', 'size', sum_isnan, percent_isnan, noutlier, percent_noutlier],
            value_intensity_predict=['sum', 'min', 'mean', 'max', 'count', 'size', sum_isnan, percent_isnan, noutlier, percent_noutlier],
            value_speed_predict=['sum', 'min', 'mean', 'max', 'count', 'size', sum_isnan, percent_isnan, noutlier, percent_noutlier],
        )

        # Copiar DataFrame y realizar cálculos estadísticos
        df = self.df_final.copy()
        df = df.groupby(groups).agg(aggs).reset_index()
        df.columns = df.columns.map("_".join).str.strip("_")

        df['mae']=self.score[0]

        # Almacenar el DataFrame con información estadística
        self.df_info = df

Análisis de Datos de Tráfico vehicular¶

El código realiza un análisis de datos de tráfico vehicular utilizando el módulo datetime para manejar fechas y horarios. A continuación se resumen los pasos principales:

  1. Importar el módulo datetime: El código importa el módulo datetime para trabajar con fechas y horarios.

  2. Asignar un código de carril: Se asigna un código de carril a la variable rail.

  3. Definir las fechas mínima y máxima: Se definen las fechas mínima y máxima para el análisis, especificando el 1 de junio de 2022 y el 1 de junio de 2023 respectivamente.

  4. Definir columnas de características: Se definen las columnas de características que se utilizarán en el modelo. Estas incluyen la semana del año, el día de la semana y la hora del día.

  5. Definir columnas objetivo: Se definen las columnas objetivo que contienen los valores reales de intensidad y velocidad.

  6. Definir columnas de predicción: Se definen las columnas de predicción que contendrán los valores predichos de intensidad y velocidad generados por el modelo.

  7. Crear instancia de la clase MDL: Se crea una instancia de una clase MDL (posiblemente definida en otro lugar del código) con los parámetros especificados, incluyendo el código de carril, fechas, columnas de características, columnas objetivo y columnas de predicción.

In [ ]:
# Asignar un código de carril a la variable 'rail'
rail = '0303134'

# Definir la fecha mínima y máxima para el análisis
date_min = datetime.datetime(2022, 6, 1, 0)  # 1 de junio de 2022 a las 00:00
date_max = datetime.datetime(2023, 6, 1, 0)  # 1 de junio de 2023 a las 00:00

# Definir las columnas de características que se utilizarán en el modelo
feature_columns = [
    'week_of_year',    # Semana del año
    'day_of_week',     # Día de la semana (0: lunes, 6: domingo)
    'hour',            # Hora del día (0-23)
]

# Definir las columnas objetivo (valores reales) que se utilizarán en el modelo
target_columns = [
    'value_intensity_real',    # Valor real de la intensidad
    'value_speed_real',        # Valor real de la velocidad
]

# Definir las columnas de predicción que se generarán a través del modelo
predict_columns = [
    'value_intensity_predict',    # Valor predicho de la intensidad
    'value_speed_predict',        # Valor predicho de la velocidad
]

# Crear una instancia de la clase MDL con los parámetros especificados
mdl = MDL(
    **dict(
        rail=rail,
        date_min=date_min,
        date_max=date_max,
        feature_columns=feature_columns,
        target_columns=target_columns,
        predict_columns=predict_columns
    )
)
263/263 [==============================] - 0s 1ms/step - loss: 13.9766 - mean_absolute_error: 13.9766
274/274 [==============================] - 1s 1ms/step

El resultado que estás viendo es el resultado de una iteración de entrenamiento de un modelo de TensorFlow.explicación de los valores que se muestran:

  • 263/263: Esto indica que se han completado 263 pasos (iteraciones) de entrenamiento. La primera cifra (263) representa los pasos completados, y la segunda cifra (263) representa el total de pasos programados para esta ejecución.

  • - 0s 2ms/step: Esto indica el tiempo que tomó realizar cada paso de entrenamiento. En este caso, cada paso tomó aproximadamente 2 milisegundos.

  • loss: 13.6875: "loss" se refiere a la función de pérdida (loss function) que se utiliza para medir la discrepancia entre las predicciones del modelo y los valores reales del conjunto de datos. En este caso, el valor de la pérdida es 13.6875. Una pérdida más baja indica un mejor ajuste del modelo a los datos de entrenamiento.

  • mean_absolute_error: 12.3: El "mean_absolute_error" (error absoluto medio) es una métrica que mide la diferencia promedio entre las predicciones del modelo y los valores reales en términos absolutos. En este caso, el valor del error absoluto medio es 12.3. Cuanto menor sea este valor, mejor será el ajuste del modelo a los datos de entrenamiento.

En resumen, los valores que estás viendo indican que en esta iteración de entrenamiento, el modelo logró un error absoluto medio de alrededor de 12.3 en el conjunto de datos de entrenamiento. Ten en cuenta que estos valores pueden variar dependiendo de factores como la arquitectura del modelo, los datos de entrenamiento y los hiperparámetros utilizados en el proceso de entrenamiento.

  • date_hour: La fecha y hora en que se registraron los datos.
  • rail: El número o identificador del tramo de carril.
  • year: El año en que se registraron los datos.
  • month: El mes en que se registraron los datos.
  • day: El día del mes en que se registraron los datos.
  • hour: La hora del día en que se registraron los datos.
  • day_of_week: El día de la semana en que se registraron los datos (0 es domingo, 6 es sábado).
  • week_of_year: El número de la semana en el año.
  • day_of_year: El número del día en el año.
  • value_intensity_real: La intensidad de tráfico real registrada en ese momento.
  • value_speed_real: La velocidad real de tráfico registrada en ese momento.
  • value_intensity_predict: La intensidad de tráfico pronosticada en ese momento.
  • value_speed_predict: La velocidad de tráfico pronosticada en ese momento.
In [ ]:
df=mdl.df_final.copy()
df
Out[ ]:
date_hour rail year month day hour day_of_week week_of_year day_of_year value_intensity_real value_speed_real value_intensity_predict value_speed_predict
0 2022-06-01 00:00:00 303134 2022 6 1 0 2 22 152 28.0 7.0 29.897038 7.664293
1 2022-06-01 01:00:00 303134 2022 6 1 1 2 22 152 17.0 6.0 16.450335 4.530858
2 2022-06-01 02:00:00 303134 2022 6 1 2 2 22 152 12.0 3.0 11.440790 2.903398
3 2022-06-01 03:00:00 303134 2022 6 1 3 2 22 152 15.0 5.0 12.876755 2.924136
4 2022-06-01 04:00:00 303134 2022 6 1 4 2 22 152 22.0 5.0 23.556971 6.685097
... ... ... ... ... ... ... ... ... ... ... ... ... ...
8756 2023-05-31 20:00:00 303134 2023 5 31 20 2 22 151 248.0 20.0 177.403061 17.027924
8757 2023-05-31 21:00:00 303134 2023 5 31 21 2 22 151 212.0 18.0 134.948257 16.197107
8758 2023-05-31 22:00:00 303134 2023 5 31 22 2 22 151 192.0 18.0 79.100922 13.662395
8759 2023-05-31 23:00:00 303134 2023 5 31 23 2 22 151 132.0 18.0 48.094742 11.962787
8760 2023-06-01 00:00:00 303134 2023 6 1 0 3 22 152 NaN NaN 29.715658 7.216057

8761 rows × 13 columns

Interpretación de la resultados¶

  • Datos temporales:

    • date_hour_min: Fecha y hora mínimas de la serie de datos.
    • date_hour_max: Fecha y hora máximas de la serie de datos.
  • Intensidad real:

    • value_intensity_real_sum: Suma total de la intensidad real.
    • value_intensity_real_min: Valor mínimo de la intensidad real.
    • value_intensity_real_mean: Valor promedio (media) de la intensidad real.
    • value_intensity_real_max: Valor máximo de la intensidad real.
    • value_intensity_real_count: Número total de valores en la serie.
    • value_intensity_real_size: Tamaño total de la serie.
    • value_intensity_real_sum_isnan: Número de valores ausentes (NaN) en la serie.
    • value_intensity_real_percent_isnan: Porcentaje de valores ausentes en la serie.
    • value_intensity_real_noutlier: Número de valores atípicos en la serie.
    • value_intensity_real_percent_noutlier: Porcentaje de valores atípicos.
  • Velocidad real:

    • value_speed_real_sum: Suma total de la velocidad real.
    • value_speed_real_min: Valor mínimo de la velocidad real.
    • value_speed_real_mean: Valor promedio (media) de la velocidad real.
    • value_speed_real_max: Valor máximo de la velocidad real.
    • value_speed_real_count: Número total de valores en la serie.
    • value_speed_real_size: Tamaño total de la serie.
    • value_speed_real_sum_isnan: Número de valores ausentes (NaN) en la serie.
    • value_speed_real_percent_isnan: Porcentaje de valores ausentes.
    • value_speed_real_noutlier: Número de valores atípicos en la serie.
    • value_speed_real_percent_noutlier: Porcentaje de valores atípicos.
  • Intensidad predición:

    • value_intensity_predict_sum: Suma total de la intensidad predición.
    • value_intensity_predict_min: Valor mínimo de la intensidad predición.
    • value_intensity_predict_mean: Valor promedio (media) de la intensidad predición.
    • value_intensity_predict_max: Valor máximo de la intensidad predición.
    • value_intensity_predict_count: Número total de valores en la serie.
    • value_intensity_predict_size: Tamaño total de la serie.
    • value_intensity_predict_sum_isnan: Número de valores ausentes (NaN) en la serie.
    • value_intensity_predict_percent_isnan: Porcentaje de valores ausentes en la serie.
    • value_intensity_predict_noutlier: Número de valores atípicos en la serie.
    • value_intensity_predict_percent_noutlier: Porcentaje de valores atípicos.
  • Velocidad predición:

    • value_speed_predict_sum: Suma total de la velocidad predición.
    • value_speed_predict_min: Valor mínimo de la velocidad predición.
    • value_speed_predict_mean: Valor promedio (media) de la velocidad predición.
    • value_speed_predict_max: Valor máximo de la velocidad predición.
    • value_speed_predict_count: Número total de valores en la serie.
    • value_speed_predict_size: Tamaño total de la serie.
    • value_speed_predict_sum_isnan: Número de valores ausentes (NaN) en la serie.
    • value_speed_predict_percent_isnan: Porcentaje de valores ausentes.
    • value_speed_predict_noutlier: Número de valores atípicos en la serie.
    • value_speed_predict_percent_noutlier: Porcentaje de valores atípicos.
  • Error absoluto medio (MAE):

    • mae: Valor del error absoluto medio en las predicciones.
In [ ]:
df_tmp=mdl.df_info.copy()
df_tmp=df_tmp.T.reset_index().rename(columns={'index':'variable', 0:'value'})
df_tmp
Out[ ]:
variable value
0 rail 303134
1 date_hour_min 2022-06-01 00:00:00
2 date_hour_max 2023-06-01 00:00:00
3 value_intensity_real_sum 1363341.0
4 value_intensity_real_min 0.0
5 value_intensity_real_mean 159.194418
6 value_intensity_real_max 754.0
7 value_intensity_real_count 8564
8 value_intensity_real_size 8761
9 value_intensity_real_sum_isnan 197
10 value_intensity_real_percent_isnan 2.248602
11 value_intensity_real_noutlier 84
12 value_intensity_real_percent_noutlier 0.009588
13 value_speed_real_sum 148001.0
14 value_speed_real_min 0.0
15 value_speed_real_mean 17.281761
16 value_speed_real_max 125.0
17 value_speed_real_count 8564
18 value_speed_real_size 8761
19 value_speed_real_sum_isnan 197
20 value_speed_real_percent_isnan 2.248602
21 value_speed_real_noutlier 80
22 value_speed_real_percent_noutlier 0.009131
23 value_intensity_predict_sum 1267243.5
24 value_intensity_predict_min 9.475908
25 value_intensity_predict_mean 144.645981
26 value_intensity_predict_max 326.907135
27 value_intensity_predict_count 8761
28 value_intensity_predict_size 8761
29 value_intensity_predict_sum_isnan 0
30 value_intensity_predict_percent_isnan 0.0
31 value_intensity_predict_noutlier 0
32 value_intensity_predict_percent_noutlier 0.0
33 value_speed_predict_sum 135790.84375
34 value_speed_predict_min 2.641654
35 value_speed_predict_mean 15.499469
36 value_speed_predict_max 19.839184
37 value_speed_predict_count 8761
38 value_speed_predict_size 8761
39 value_speed_predict_sum_isnan 0
40 value_speed_predict_percent_isnan 0.0
41 value_speed_predict_noutlier 239
42 value_speed_predict_percent_noutlier 0.02728
43 mae 13.976562

** Conclusiones de la Gráfica de Dispersión (Intensidad vs Velocidad)

  • La variable velocidad muestra una alta dispersión en los datos, con la presencia de numerosos valores atípicos.

  • Por otro lado, la variable intensidad exhibe una variación mínima en la mayoría de los casos, indicando una relativa estabilidad en sus valores.

  • Se observa una relación entre la intensidad y la velocidad que se asemeja a una función subamortiguada, sugiriendo una correlación no lineal entre estas dos variables.

In [ ]:
df=mdl.df_final.copy()
fig = px.scatter(df, x="value_intensity_real", y="value_speed_real", marginal_y="box", marginal_x="box")
fig.show()

** Conclusiones de la Gráfica de Dispersión

La gráfica de dispersión presenta una relación entre dos variables: intensidad pronosticada y velocidad pronosticada. A través del análisis de la gráfica, se pueden destacar las siguientes conclusiones:

  • El modelo ha generalizado de manera adecuada, ya que la gráfica revela una relación clara entre las variables. Esta relación se identifica como una función exponencial subamortiguada.

  • Se observa que los valores pronosticados se alinean con la tendencia de la gráfica, lo que sugiere que el modelo ha capturado eficazmente la naturaleza de la relación entre intensidad y velocidad pronosticada.

  • Es importante destacar que los valores pronosticados en términos de magnitud son en general menores que los valores reales. Esto puede atribuirse al hecho de que el conjunto de datos de entrenamiento ha excluido valores atípicos. Esta selección puede haber influido en la capacidad del modelo para predecir valores extremos.

En resumen, la gráfica de dispersión refleja una relación exponencial subamortiguada entre intensidad y velocidad pronosticada. El modelo ha logrado una buena generalización, pero es esencial tener en cuenta la influencia de los valores atípicos excluidos en las predicciones de magnitud.

In [ ]:
df=mdl.df_final.copy()
fig = px.scatter(df, x="value_intensity_predict", y="value_speed_predict", marginal_y="box", marginal_x="box")
fig.show()

Conclusiones de la Gráfica de Histogramas

La gráfica muestra la sobreposición de histogramas de dos variables: intensidad real e intensidad pronosticada. Se observa claramente que ambas variables tienen la misma silueta, lo que sugiere una relación cercana entre ellas.

Además, se aprecia con claridad que los valores de la intensidad pronosticada son menores en magnitud en comparación con la intensidad real. Esta diferencia se debe al hecho de que el modelo fue entrenado excluyendo valores atípicos y extremos, lo que influyó en la magnitud de los pronósticos generados.

En resumen, la gráfica proporciona evidencia de la correspondencia entre las dos variables y destaca la influencia del entrenamiento del modelo en los valores pronosticados.

In [ ]:
df=mdl.df_final.copy()
fig = px.histogram(df, x=["value_intensity_real",'value_intensity_predict'], marginal='box',histnorm='probability density')
fig.show()

Conclusiones de la Gráfica de Histogramas

La gráfica muestra la sobreposición de histogramas para dos variables: velocidad real y velocidad pronosticada. Se observa claramente que ambas variables tienen una silueta similar, lo que sugiere una relación entre ellas.

Además, es evidente que los valores de la velocidad pronosticada son menores en magnitud en comparación con la velocidad real. Esta discrepancia se debe a que el modelo de pronóstico fue entrenado sin valores atípicos ni extremos, lo que influye en la escala de los valores pronosticados.

En resumen, la gráfica de histogramas revela la similitud entre las velocidades reales y pronosticadas, así como la diferencia en magnitud debido al enfoque del modelo en los valores más comunes al ser entrenado.

In [ ]:
df=mdl.df_final.copy()
fig = px.histogram(df, x=["value_speed_real",'value_speed_predict'], marginal='box',histnorm='probability density')
fig.show()

Conclusiones sobre la Gráfica de Cajas y Bigotes¶

En el análisis de la gráfica de cajas y bigotes, se ha observado una correlación directa entre los pronósticos y los valores reales a lo largo de los días. Esta conclusión se sustenta en los siguientes puntos:

  • Coincidencia de Medias: Se ha notado que las medias de los pronósticos y los valores reales muestran una marcada coincidencia. Esta similitud entre las medias indica que el modelo ha logrado capturar el comportamiento general de los días y ha generado pronósticos cercanos a los valores reales.

  • Generalización del Comportamiento: El modelo ha logrado generalizar exitosamente el comportamiento de los días. Esto significa que no solo se ha ajustado a los datos de entrenamiento, sino que también puede aplicar el conocimiento aprendido a datos no vistos previamente. Esta capacidad de generalización es crucial para la precisión de los pronósticos.

En resumen, la gráfica de cajas y bigotes refleja una correlación positiva entre los pronósticos y los valores reales a lo largo de los días. La coincidencia de las medias y la habilidad del modelo para generalizar el comportamiento son indicativos de un buen rendimiento en la predicción de los valores. Esto sugiere que el modelo es confiable y preciso en su capacidad para prever los valores futuros basados en el histórico de datos.

In [ ]:
df=mdl.df_final.copy()

df=pd.melt(df, id_vars='day_of_week', value_vars=['value_intensity_real','value_intensity_predict'])

variable=['value_intensity_real','value_intensity_predict']

df_tmp=df.query("variable in @variable")

fig=px.box(df_tmp, x='day_of_week', y='value', color='variable')
fig.show()
In [ ]:
df=mdl.df_final.copy()

df=pd.melt(df, id_vars='day_of_week', value_vars=['value_speed_real','value_speed_predict'])

variable=['value_speed_real','value_speed_predict']

df_tmp=df.query("variable in @variable")

fig=px.box(df_tmp, x='day_of_week', y='value', color='variable')
fig.show()

Conclusiones¶

En base a los resultados obtenidos, se puede concluir que el modelo desarrollado es aceptable y demuestra una capacidad satisfactoria para generalizar correctamente. Esto abre la puerta a su aplicación en diversos contextos.

Una de las principales utilidades del modelo es su capacidad para realizar predicciones en presencia de datos faltantes. La habilidad para llenar los vacíos en los conjuntos de datos y proporcionar estimaciones razonables es valiosa en escenarios donde la integridad de los datos es crucial para la toma de decisiones.

Además, el modelo muestra una habilidad prometedora para generar pronósticos. Esta capacidad de prever tendencias futuras basadas en los patrones identificados en los datos históricos puede ser de gran utilidad en la planificación estratégica y en la anticipación de posibles escenarios.

En resumen, el modelo no solo supera las expectativas en términos de generalización, sino que también ofrece aplicaciones prácticas en la imputación de datos faltantes y en la generación de pronósticos. Sin embargo, se recomienda un seguimiento continuo para evaluar y mejorar su rendimiento en diferentes situaciones y conjuntos de datos.